home *** CD-ROM | disk | FTP | other *** search
- ;
- ; Program to print the segment, and offset info of an interrupt handler.
- ; Version One, Steve Kemp '95
- ;
- ; Operation, either
- ;
- ; INTVIEW [/?] - Print info
- ; INTVIEW /A - Print all interrupt handlers addresses
- ; INTVIEW xx - xx = Decimal int. number to print location of
- ; INTVIEW xxh - xx = Hexidecimal int. number to print location of.
- ;
- ;
- ;
- ; e.g. Find the location of the int 13h handler, either use:
- ;
- ; INTVIEW 13h, or INTVIEW 19 (13h=19 decimal)
- ;
-
- parser:
- mov SI,80h
- parse_loop:
- inc SI ; Get ready for next character
- mov Dl,[SI] ; Get character from command tail
- cmp Dl,'/' ; Switch??
- jz found_slash ; If so goto switch routine
- cmp Dl,0Dh ; End of tail??
- jnz parse_loop ; If not repeat
-
- cmp SI,81h ; Still at start of tail??
- jnz number_entered ; If not continue
-
- mov DX,info_message ; Else queue up error message
- call print_string ; Print it
- jmp return2DOS ; and return to DOS
-
- number_entered:
- call calculate_number ; Calculate number on command line
- ; Store it in int_number
-
- mov AX,[int_number] ; Get the number calculated
- cmp AX,255 ; Is it bigger than 255??
- jle not_too_big ; If not continue
-
- mov DX,too_big ; Queue up 'Too big message'
- call print_string ; Print it
- jmp return2DOS ; Stop
-
- not_too_big:
- call print_initial ; Print the int number selected
- call display_address ; Now print the actual segment:offset
- jmp return2DOS ; Return to DOS
-
- found_slash:
- inc SI ; Point to next letter
- mov Dl,[SI] ; Get it into Dl
- cmp Dl,'?' ; ? ?? If so print info about program
- jz info
- or Dl,32 ; Convert to ASCII lowercase
- cmp Dl,'a'
- jz do_all ; /a ?? If so go setup printing all
- push DX ; Otherwise invalid switch. Save it
- mov DX,invalid_switch ; Print invalid switch message
- call print_string ; Here
- pop DX ; Get back saved letter
- add Dl,'A'-'a' ; Print uppercase version of letter
- mov Ah,02 ; Print a single character
- int 21h ; Now!
- return2DOS:
- mov Ah,4ch ; Return to DOS
- int 21h ; There!
-
- info:
- mov DX,info_message ; Point to info. string
- call print_string ; Print the string
- jmp return2DOS ; finished!
-
- ;
- ; Pleasant routine to print out all the interrupts, one after the other
- ; by looping and increasing the int. number to display on each iteration
- ;
- do_all:
- mov CX,00 ; Counter
- do_all_loop:
- push CX ; Save counter on the stack
- mov [int_number],CX ; Adjust the number to print
- call print_initial ; print the initial message
- call display_address ; Now print the handlers address
- call print_crlf ; Print a CR, LF
- pop CX
- inc Cl
- cmp Cl,00
- jnz do_all_loop
- jmp return2DOS
-
- ;
- ; The following routine determines whether the input number is hex or
- ; decimal, and calculates it, storing the result into the buffer 'int_number'
- ;
- calculate_number:
- mov SI,82h ; Number is first parameter on Command
- mov DI,ascii_buffer ; Put a copy of it into the temporary
- movsw ; buffer
- movsb
-
- dec SI ; Point to buffer+1
- mov CX,2 ; Three bytes long max
- hex_or_dec:
- mov Dl,[si] ; Get a letter
- or Dl,32
- cmp dl,"h" ; Is it a hex number marker??
- jz hex_number
- inc SI
- loop hex_or_dec ; Repeat
-
- decimal_number:
- mov CX,0003
- mov AX,0000
- mov SI,ascii_buffer
- test_validity:
- mov Dl,[SI]
- cmp Dl,'0'-1
- jle end_of_number
- cmp Dl,'9'+1
- jge end_of_number
- inc AX
- inc SI
- loop test_validity
-
- end_of_number:
- mov SI,ascii_buffer ; Reset pointer
- mov Dh,00h ; Blank high byte of Dh
- cmp AX,0001
- jz one_byte
- cmp AX,0002
- jz two_byte
- cmp AX,0003
- jz three_byte
- ret
-
- one_byte: ; We have a one ASCII-digit number
- mov Dl,[SI] ; Get the digit
- sub Dl,'0' ; Convert it.
- mov word ptr [int_number],DX ; Dh=00 already
- ret
-
- two_byte:
- mov Dl,[SI] ; Get the most significant number
- sub Dl,'0' ; Convert it
- mov Al,10 ; Multiply it by ten, high byte =00h
- mul DX ; Result in AX
- xor DX,DX ; Set DX=0000
- inc SI ; Point to next number
- mov Dl,[SI] ; Get it.
- sub Dl,'0' ; Canvert that
- add DX,AX ; Add it to total
- mov word ptr [int_number],DX ; Store it in the store
- ret ; Return
-
- three_byte:
- mov Dl,[Si] ; Get first letter
- sub Dl,'0' ; Convert it to 0-9
- mov AX,100 ; We want to multiply it by 100
- mul DX ; Do it. Returns the result in AX
- mov BX,AX ; Save it in BX
- inc SI ; Point to next letter
- call two_byte ; Proceed as if it were only two digits
- add DX,BX ; Add the two digit total to the preserved
- mov word ptr [int_number],DX ; BX, and store it in the store
- ret ; Return
-
-
- ;
- ; Hex numbers handled here
- ;
- hex_number:
- mov SI,ascii_buffer ; Point to beginning of ASCII buffer
- mov Dl,[SI] ; Get a character
- inc SI ; Move pointer up by one
- mov Dh,[SI] ; Get another character
- or Dh,32 ; Conver secong character to lower case
- cmp Dh,'h' ; Is it a 'h'
- jz one_digit_hex ; If so number is one ASCII-byte long
-
- two_digit_hex: ; Else it MUST be two ASCII-bytes long
- cmp Dl,'9'
- jle less_than_nine_1 ; Is it a number??
- or Dl,32 ; If not its a letter, lowercase it becomes
- sub dl,'a'-10-'0' ; Adjust value
- less_than_nine_1:
- sub Dl,'0' ; Convert it to number 0-15
- mov AX,16 ; Get ready to multiply by 16
- mov Dh,00
- mul DX ; Do it! (Result in AX)
- push AX ; Save result on stack
- mov Dl,[SI] ; Get next digit
- call one_digit_hex ; Treat it as a one digit number
- pop AX ; Restore the value that we saved
- add AX,DX ; Add high+low results
- mov [int_number],AX ; Finally store the result in the bufffer
- ret ; Finished (Phew!)
-
- one_digit_hex:
- cmp Dl,'9' ; Is it a digit??
- jle less_than_nine_2 ; If so goto digit routine
- or dl,32 ; Convert letter to lower case
- sub Dl,'a'-'9'-1 ; Adjust it
- less_than_nine_2:
- sub Dl,'0' ; Convert it to a number 0-15
- mov Dh,00 ; Blank out high byte
- mov [int_number],DX ; Store in the buffer
- ret ; Return
-
- print_initial:
- mov DX,initial_message ; Queue up message
- call print_string ; Print it
- mov AX,[int_number] ; Get the interupt number
- mov Ah,Al ; Put it in Ah
- call print_hex ; Print out Ah
- mov DX,final_message ; Queue up message
- call print_string ; Print it
- ret ; Return
-
- ;
- ; This routine prints the contents of Ah as a two-byte hex number.
- ;
- print_hex:
- mov al,ah
- shr ah,1
- shr ah,1
- shr ah,1
- shr ah,1
- cmp ah,9
- jbe next1
- add ah,7
- next1:
- add ah,'0'
- and al,0fh
- cmp al,9
- jbe next2
- add al,7
- next2:
- add al,'0'
- push cx
- mov cl,ah
- mov ch,al
- mov Ah,02
- mov Dl,cl
- int 21h
- mov Ah,02
- mov Dl,ch
- int 21h
- pop cx
- ret
-
-
- ;
- ; This routine actually prints the segment:offset info of the interrupt
- ; number stored in 'int_number'
- ;
- Display_address:
- mov AX,0004 ; Multiply int number by four
- mov BX,[int_number] ; Get int. number
- mul BX ; Do the multiplication
- mov SI,AX ; Set the pointer accordingly
-
- push DS ; Save the data segment
- xor AX,AX ; AX=0000
- push AX ; Store the zero value on the stack
- pop DS ; Data segment=0000
-
- mov AX,[SI] ; Get the offset of the handler
- inc SI ; increase pointer
- inc SI ; increase pointer to point to the offset
- mov BX,[SI] ; Get the offset
- pop DS ; Restore data segment
-
- mov word ptr [offset_buffer],AX ; Store the segment
- mov word ptr [segment_buffer],BX ; Store the offset
-
- push AX
- mov CX,BX
- pop BX ; Swap the registers around
- mov AX,CX
-
- push BX ; Keep a copy of the offset on the stack
- push AX ; And keep the segment
- call print_hex ; Print the high byte of the segment
- pop AX
- mov Ah,Al
- call print_hex ; Print the lowbyte of the segment
-
- mov Ah,02 ; Print a single letter
- mov Dl,':' ; A seporater
- int 21h ; Now!
-
- pop BX ; Restore the offset
- push BX ; Save it for later
- mov Ah,Bh ; Print the highbyte
- call print_hex
- pop AX
- mov Ah,Al
- call print_hex ; Print the low byte
-
- ret ; Return
-
- print_crlf:
- mov DX,lfcr ; Point to linefeed, CR
- print_string:
- mov Ah,09h ; Get ready to output the string addressed
- int 21h ; By DX. Do it.
- ret ; Return
-
- ; **************************************************************************
- ; * Output Strings and Data area *
- ; ********************************
-
- invalid_switch:
- db "Invalid switch - /","$"
- too_big:
- db "Interupt number too big!","$"
- info_message:
- db "INTVIEW Version One - Steven Kemp 1995",0ah,0dh
- db 0ah,0dh
- db " Usage: INTVIEW [/?] - Show this information",0ah,0dh
- db 0ah,0dh
- db " INTVIEW xxx[h] - Show the segment:offset information",0ah,0dh
- db " of int. number xxx (Assumes decimal)",0ah,0dh
- db " - Can overide by the 'h' suffix.",0ah,0dh
- db 0ah,0dh
- db " INTVIEW /A - Show the info on _all_ the interrupts",0ah,0dh
- db "$"
- initial_message:
- db "Interrupt number ","$"
- final_message:
- db "h has its handler at ","$"
- lfcr:
- db 0A,0Dh,"$"
-
- ascii_buffer:
- db 00,00,00
-
- int_number:
- dw 0000h
-
- offset_buffer:
- dw 0000h
-
- segment_buffer:
- dw 0000h
-